﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices; 

namespace HOOMT
{
    public partial class ObjectSpecificationDialog : Form
    {
        
        public ObjectSpecificationDialog()
        {
            InitializeComponent();
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
        }
        #region 属性
        //*************************************************************************
        //“临时”方法列表，根据添加方法对话框实时更新方法对话框的显示，（显示更新)
        //方法对话框返回 DialogResult.OK 时，用临时方法列表更新对象的方法列表（数据更新）
        //method
        private List<Method> temporaryMethodList = new List<Method>();
        public List<Method> TemporaryMethodList
        {
            get{return temporaryMethodList;}
            set{temporaryMethodList = value;}
        }
        public RichTextBox MethodShowBox
        {
            get{return methodsShowBox;}
            set{methodsShowBox = value;}
        }
        //attribute
        private List<Attribute> temporaryAttributeList = new List<Attribute>();
        public RichTextBox AttributeShowBox
        {
            get { return attributesShowBox; }
            set { attributesShowBox = value; }
        }
        public List<Attribute> TemporaryAttributeList
        {
            get { return temporaryAttributeList; }
            set { temporaryAttributeList = value; }
        }
        //NFR
        private List<NonFunctionRequirment> temporaryObjectNFRList = new List<NonFunctionRequirment>();

        internal List<NonFunctionRequirment> TemporaryObjectNFRList
        {
            get { return temporaryObjectNFRList; }
            set { temporaryObjectNFRList = value; }
        }
        public RichTextBox NonFunctionShowBox
        {
            get { return nonFunctionShowBox; }
            set { nonFunctionShowBox = value; }
        }
        //Relations
        private List<String> temporaryRelationsList = new List<string>();

        public List<String> TemporaryRelationsList
        {
            get { return temporaryRelationsList; }
            set { temporaryRelationsList = value; }
        }
        public RichTextBox RelationsShowBox
        {
            get{ return relationsShowBox;}
            set { relationsShowBox = value; }
        }
        //
        private int myLine, offSet;//记录选中行号，选中行偏移(行起始位置)
        private bool hasSelectedItem = false;

        //private String objectName;
        public string ObjectName
        {
            get { return objectName.Text; }
            set { objectName.Text = value; }
        }

        private HighOrderObjectDiagram parentOrderObjectDiagram;
        public  HighOrderObjectDiagram ParentOrderObjectDiagram
        {
            get { return parentOrderObjectDiagram; }
            set { parentOrderObjectDiagram = value; }
        }

        //private String type;   能否用Type命名？？
        public string Type
        {
            get { return objectType.Text; }
            set { objectType.Text = value; }
        }
        //private String stereoType;

        public string StereoType
        {
            get { return objectStereotype.Text; }
            set { objectStereotype.Text = value; }
        }
        //private String exportControl;
        public string ExportControl
        {
            get
            {
            if (publicRadio.Checked)
                return "Public";
            else if (privateRadio.Checked)
                return "Private";
            else
                return "Protected";
             }
            set
            {
                if (value.Equals("Public"))
                    publicRadio.Checked = true;
                else if (value.Equals("Private"))
                    privateRadio.Checked = true;
                else
                    protectedRadio.Checked = true;
            }
        }
        //private String documentation;
        public string Documentation
        {
            get { return objectDoc.Text; }
            set { objectDoc.Text = value; }
        }
        //*************************************************************************
        #endregion

        #region 对象属性
        //*************************************************************************
        private void attributesShowBox_MouseDown(object sender, MouseEventArgs e)
        {
            selectedRow((RichTextBox)sender);
            HideCaret(((RichTextBox)sender).Handle);//隐藏光标
        }
        //
        private void addAttributeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AttributeAddDialog addDialog = new AttributeAddDialog();

            initAttrAddDiallog(addDialog);

            if (addDialog.ShowDialog() == DialogResult.OK)
            {
                if (!string.IsNullOrWhiteSpace(addDialog.AttributeType) && !string.IsNullOrWhiteSpace(addDialog.AttributeName))
                {
                    addAttributetoTemporaryAttributeList(addDialog);
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(addDialog.AttributeType))
                        MessageBox.Show("Invalid Inputs，AttributeType is null!");
                    else
                        MessageBox.Show("Invalid Inputs，AttributeName is null!");
                }
            }
            hasSelectedItem = false;
        }
        //
        private void modefyAttributeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (hasSelectedItem)
            {
                string selectedItem = attributesShowBox.Lines[myLine];
                AttributeAddDialog modifyForm = initAttrModifyFormwithSelectedItem(selectedItem);

                if (modifyForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    updateTemporaryAttrList(modifyForm, selectedItem);
                }
                hasSelectedItem = false;
            }
        }
        //
        private void deleteAttributeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (hasSelectedItem)
            {
                deleteAttribute();
            }
        }
        //***
        private void initAttrAddDiallog(AttributeAddDialog addDialog)
        {
            addDialog.ParentAttrCombox.Items.Clear();
            if (parentOrderObjectDiagram != null)
            {
                foreach (Attribute attr in parentOrderObjectDiagram.AttributeList)
                {
                    addDialog.ParentAttrCombox.Items.Add(attr.AttributeName);
                }
                if (parentOrderObjectDiagram.AttributeList.Count != 0)
                {
                    addDialog.ParentAttrCombox.SelectedIndex = 0;
                }
            }
        }
        //
        private void addAttributetoTemporaryAttributeList(AttributeAddDialog addDialog)
        {
            Attribute attribute = new Attribute(addDialog.AccessModifier.Trim(), addDialog.AttributeType.Trim(),
                        addDialog.AttributeName.Trim(), addDialog.InitialValue.Trim());

            setAttrParent(addDialog, attribute);

            this.attributesShowBox.Text += attribute.ToString();
            this.attributesShowBox.Text += "\n";

            this.TemporaryAttributeList.Add(attribute);
        }
        //
        private void setAttrParent(AttributeAddDialog addDialog, Attribute attribute)
        {
            if (parentOrderObjectDiagram != null)
            {
                foreach (Attribute attr in parentOrderObjectDiagram.AttributeList)
                {
                    if (addDialog.ParentAttrCombox.Text.Equals(attr.AttributeName))
                    {
                        attribute.parentAttr = attr;
                        attribute.parentAttrId = attr.id;
                        break;
                    }
                }
            }
        }
        //
        private AttributeAddDialog initAttrModifyFormwithSelectedItem(string str)
        {
            
            AttributeAddDialog resulte = new AttributeAddDialog();
            resulte.Text = "AttributeModifyDialog";
            //设置方法对话框的初始显示值
            string[] arrstr;
            arrstr = str.Split();
            resulte.AccessModifier = arrstr[0];
            resulte.AttributeType = arrstr[2];//因为中间有两个空格
            resulte.AttributeName = arrstr[4];
            //更改时不现实初始值
            //resulte.InitialValue = arrstr[6].Substring(0, arrstr[6].Length - 1);//去掉最后的分号

            return resulte;
        }
        //
        private void updateTemporaryAttrList(AttributeAddDialog modifyForm, string str)
        {
            if (!string.IsNullOrWhiteSpace(modifyForm.AttributeType) && !string.IsNullOrWhiteSpace(modifyForm.AttributeName))
            {
                Attribute attr = new Attribute(modifyForm.AccessModifier.Trim(), modifyForm.AttributeType.Trim(),
                    modifyForm.AttributeName.Trim(), modifyForm.InitialValue.Trim());
                //更新显示
                StringBuilder str2 = new StringBuilder();
                str2.Append(attributesShowBox.Text);
                str2.Replace(str, attr.ToString());
                attributesShowBox.Text = str2.ToString();
                //更新临时列表
                temporaryAttributeList[myLine] = attr;
            }
        }
        //
        private void deleteAttribute()
        {
            StringBuilder str1 = new StringBuilder();
            str1.Append(attributesShowBox.Text);
            str1.Remove(offSet, attributesShowBox.Lines[myLine].Length + 1);
            attributesShowBox.Text = str1.ToString();

            temporaryAttributeList.RemoveAt(myLine);

            Invalidate();
            hasSelectedItem = false;
        }
        //*************************************************************************
        #endregion

        #region 对象方法
        //*************************************************************************
        private void methodsShowBox_MouseDown(object sender, MouseEventArgs e)
        {
            //选中Item
            if (methodsShowBox.Text.Length != 0)
            {
                int myStart = this.methodsShowBox.SelectionStart;//鼠标点击位置
                myLine = this.methodsShowBox.GetLineFromCharIndex(myStart);//获取选中行号(从0开始)
                if (methodsShowBox.Lines[myLine].Length > 0)
                {
                    //计算选中的行的开始位置
                    offSet = 0;
                    for (int i = 0; i < myLine; i++)
                    {
                        offSet += methodsShowBox.Lines[i].Length;
                        offSet += 1;//"\n"
                    }
                    //选中行
                    methodsShowBox.Select(offSet, methodsShowBox.Lines[myLine].Length);
                    hasSelectedItem = true;
                }
                else
                    hasSelectedItem = false;
            }
            else
                hasSelectedItem = false;
            HideCaret(((RichTextBox)sender).Handle);//隐藏光标
        }
        //
        private void addMethodToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MethodAddDialog addDialog = new MethodAddDialog();

            initMethodAddDiallog(addDialog);

            if (addDialog.ShowDialog() == DialogResult.OK)
            {
                if (!string.IsNullOrWhiteSpace(addDialog.ReturnType) && !string.IsNullOrWhiteSpace(addDialog.MethodName))
                {
                    addAttributetoTemporaryMethodList(addDialog);
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(addDialog.ReturnType))
                        MessageBox.Show("Invalid Inputs，ReturnType is null!");
                    else
                        MessageBox.Show("Invalid Inputs，MethodName is null!");
                }
            }
            hasSelectedItem = false;//复位
        }
        //
        private void modifyMethodToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (hasSelectedItem)//在有选中条件下操作
            {
                string selectedItem = methodsShowBox.Lines[myLine];

                MethodAddDialog modifyForm = initMethodModifyFormwithSelectedItem(selectedItem);
                
                //更新修改后的显示和temporaryMethodList列表
                if (modifyForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {

                    updateTemporaryMethodList(modifyForm, selectedItem);
                }
                hasSelectedItem = false;
            }
        }
        //
        private void deleteMethodToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (hasSelectedItem)
            {
                deleteMethod();
            }
        }
        //
        private MethodAddDialog initMethodModifyFormwithSelectedItem(string str)
        {
            MethodAddDialog result = new MethodAddDialog();
            result.Text = "MethodModifyDialog";
            //设置方法对话框的初始显示值
            string[] arrstr;
            arrstr = str.Split();
            result.AccessModifier = arrstr[0];
            result.ReturnType = arrstr[2];//因为中间有两个空格
            //modifyForm.Description = arrstr[6];
            string nameAndParameter = str.Substring(arrstr[0].Length + arrstr[2].Length + 4);//4为空格数
            int parameretStart = 0, parameterLength;
            for (int i = 0; i < nameAndParameter.Length; i++)
            {
                if (nameAndParameter[i].Equals('('))
                {
                    result.MethodName = nameAndParameter.Substring(0, i);
                    parameretStart = i + 1;
                    //modifyForm.ParameterList = nameAndParameter.Substring(i + 1, nameAndParameter.Length - i - 3);//
                    //break;
                }
                else if (nameAndParameter[i].Equals(')'))
                {
                    parameterLength = i - parameretStart;
                    result.ParameterList = nameAndParameter.Substring(parameretStart, parameterLength);
                    break;
                }
            }
            return result;
        }
        //
        private void updateTemporaryMethodList(MethodAddDialog modifyForm, string str)
        {
            if (!string.IsNullOrWhiteSpace(modifyForm.ReturnType) && !string.IsNullOrWhiteSpace(modifyForm.MethodName))
            {
                 Method method = new Method(modifyForm.AccessModifier.Trim(), modifyForm.ReturnType.Trim(),
                            modifyForm.MethodName.Trim(), modifyForm.ParameterList.Trim());
                //更新显示
                StringBuilder str2 = new StringBuilder();
                str2.Append(methodsShowBox.Text);
                str2.Replace(str, method.ToString());
                methodsShowBox.Text = str2.ToString();
                //更新临时列表
                temporaryMethodList[myLine] = method;
            }
        }
        //
        private void initMethodAddDiallog(MethodAddDialog addDialog)
        {
            addDialog.ParentMethodCombox.Items.Clear();
            if (parentOrderObjectDiagram != null)
            {
                foreach (Method method in parentOrderObjectDiagram.MethodList)
                {
                    addDialog.ParentMethodCombox.Items.Add(method.MethodName);
                }
                if (parentOrderObjectDiagram.MethodList.Count != 0)
                {
                    addDialog.ParentMethodCombox.SelectedIndex = 0;
                }
            }
        }
        //
        private void addAttributetoTemporaryMethodList(MethodAddDialog addDialog)
        {
            Method method = new Method(addDialog.AccessModifier.Trim(), addDialog.ReturnType.Trim(),
                       addDialog.MethodName.Trim(), addDialog.ParameterList.Trim());

            setMethodParent(addDialog, method);

            this.methodsShowBox.Text += method.ToString();
            this.methodsShowBox.Text += "\n";
            this.TemporaryMethodList.Add(method);
        }
        //
        private void setMethodParent(MethodAddDialog addDialog, Method meth)
        {
            if (parentOrderObjectDiagram != null)
            {
                foreach (Method method in parentOrderObjectDiagram.MethodList)
                {
                    if (addDialog.ParentMethodCombox.Text.Equals(method.MethodName))
                    {
                        meth.parentMethod = method;
                        meth.parentMethodId = method.id;
                        break;
                    }
                }
            }
        }
        //
        private void deleteMethod()
        {
            StringBuilder str1 = new StringBuilder();
            str1.Append(methodsShowBox.Text);
            str1.Remove(offSet, methodsShowBox.Lines[myLine].Length + 1);
            methodsShowBox.Text = str1.ToString();
            temporaryMethodList.RemoveAt(myLine);
            Invalidate();
            hasSelectedItem = false;
        }
        //*************************************************************************
        #endregion

        #region 非功能需求
        //*************************************************************************
        private void nonFunctionShowBox_MouseDown(object sender, MouseEventArgs e)
        {
            selectedRow((RichTextBox)sender);
            HideCaret(((RichTextBox)sender).Handle);
        }
        //
        private void addNFRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NonFunctionAddDialog addDialog = new NonFunctionAddDialog(this);

            if (addDialog.ShowDialog() == DialogResult.OK)
            {
                if (!String.IsNullOrWhiteSpace(addDialog.NonFunctionName) && !String.IsNullOrWhiteSpace(addDialog.NonFunctionValue))
                {
                    addNRFtoTemporaryList(addDialog);
                }
                else
                {
                    if (String.IsNullOrWhiteSpace(addDialog.NonFunctionName))
                        MessageBox.Show("Invalid Inputs，NonFunctionName is null!");
                    else
                        MessageBox.Show("Invalid Inputs，NonFunctionValue is null!");
                }
            }
        }
        //
        private void modefyNFRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            /*if (hasSelectedItem)//在有选中条件下操作
            {
                String str = nonFunctionShowBox.Lines[myLine];
                NonFunctionAddDialog modifyForm = new NonFunctionAddDialog(this);
                modifyForm.Text = "NonFunctionAddDialog";
                //设置方法对话框的初始显示值
                String[] arrstr;
                arrstr = str.Split();
                modifyForm.AssociationType = arrstr[0];
                modifyForm.AssociationTarget = arrstr[2];
                modifyForm.NonFunctionType = arrstr[4];
                modifyForm.NonFunctionName = arrstr[6];//因为中间有两个空格
                modifyForm.NonFunctionValue = arrstr[8];

                //更新修改后的显示和temporaryMethodList列表
                if (modifyForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    if (!String.IsNullOrWhiteSpace(modifyForm.NonFunctionName) && !String.IsNullOrWhiteSpace(modifyForm.NonFunctionValue))
                    {
                        NonFunctionRequirment attr = new NonFunctionRequirment(modifyForm.AssociationType, modifyForm.AssociationTarget, modifyForm.NonFunctionType.Trim(), modifyForm.NonFunctionName.Trim(),
                            modifyForm.NonFunctionValue.Trim() );
                        //更新显示
                        StringBuilder str2 = new StringBuilder();
                        str2.Append(nonFunctionShowBox.Text);
                        str2.Replace(str, attr.ToString());
                        nonFunctionShowBox.Text = str2.ToString();
                        //更新临时列表
                        TemporaryNFRList[myLine] = attr;
                    }
                    //Invalidate();
                }
                hasSelectedItem = false;//复位
            }*/
        }
        //
        private void deleteNFRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (hasSelectedItem)
            {
                deleteNFR();
            }
        }
        //可能更改Object/Attribute/Method对应的临时列表的非功能属性
        private void addNRFtoTemporaryList(NonFunctionAddDialog addDialog)
        {
            NonFunctionRequirment requirment = new NonFunctionRequirment(addDialog.NonFunctionType, addDialog.NonFunctionName.Trim(),
                        addDialog.NonFunctionValue.Trim());
            //this.nonFunctionShowBox.Text += addDialog.AssociationTarget + ":" + requirment.ToString();
            //this.nonFunctionShowBox.Text += "\n";
            if ((addDialog.AssociationType).Equals("Object"))
            {
                temporaryObjectNFRList.Add(requirment);
            }
            else if (addDialog.AssociationType.Equals("Method"))
            {
                foreach (Method method in TemporaryMethodList)
                {
                    if ((method.MethodName).Equals(addDialog.AssociationTarget))
                        method.MethodNFRList.Add(requirment);
                }
            }
            else if (addDialog.AssociationType.Equals("Attribute"))
            {
                foreach (Attribute attr in TemporaryAttributeList)
                {
                    if ((attr.AttributeName).Equals(addDialog.AssociationTarget))
                        attr.AttributeNFRList.Add(requirment);
                }
            }
            updataNonFunctionShowBox();
        }
        //
        private void deleteNFR()
        {
            StringBuilder str1 = new StringBuilder();
            str1.Append(nonFunctionShowBox.Text);
            str1.Remove(offSet, nonFunctionShowBox.Lines[myLine].Length + 1);
            nonFunctionShowBox.Text = str1.ToString();

            deleteNFRList(myLine);

            Invalidate();
            hasSelectedItem = false;
        }
        //
        private void deleteNFRList(int line)
        {
            //依赖updataNonFunctionShowBox()方法中现实的顺序对象/属性/方法
            int subscript = line;
            if (temporaryObjectNFRList.Count == 0)
            {
                if (temporaryAttributeList.Count >= subscript + 1)
                    temporaryAttributeList[subscript].AttributeNFRList.Clear();
                else if (temporaryMethodList.Count >= subscript - temporaryAttributeList.Count + 1)
                    temporaryMethodList[subscript - temporaryAttributeList.Count].MethodNFRList.Clear();
            }
            else if (temporaryObjectNFRList.Count != 0)
            {
                if (subscript == 0)
                    temporaryObjectNFRList.Clear();
                else if (temporaryAttributeList.Count >= subscript)
                    temporaryAttributeList[subscript - 1].AttributeNFRList.Clear();
                else if (temporaryMethodList.Count >= subscript - temporaryAttributeList.Count)
                    temporaryMethodList[subscript - temporaryAttributeList.Count - 1].MethodNFRList.Clear();
            }
        }
        //
        private void updataNonFunctionShowBox()
        {
            //现实一定要根据先对象NFR,再属性NFR，再方法NFR的顺序，因为删除时依赖现实的顺序
            StringBuilder NFRBuilder = new StringBuilder();//NFR
            if (temporaryObjectNFRList.Count != 0)
            {
                NFRBuilder.AppendLine(ObjectName + "=[" + getNFRListString(temporaryObjectNFRList) + "]");//NFR
            }
            foreach (Attribute attr in TemporaryAttributeList)
            {
                if (attr.AttributeNFRList.Count != 0)
                {
                    NFRBuilder.AppendLine(attr.AttributeName + "=[" + getNFRListString(attr.AttributeNFRList) + "]");
                }
            }
            foreach (Method method in temporaryMethodList)
            {
                if (method.MethodNFRList.Count != 0)
                {
                    NFRBuilder.AppendLine(method.MethodName + "=[" + getNFRListString(method.MethodNFRList) + "]");
                }
            }
            nonFunctionShowBox.Text = NFRBuilder.ToString();
        }
        //
        private string getNFRListString(List<NonFunctionRequirment> NFRList)
        {
            StringBuilder NFRBuilder = new StringBuilder();
            foreach (NonFunctionRequirment requirment in NFRList)
            {
                NFRBuilder.Append(requirment.ToString());
            }
            return NFRBuilder.ToString();
        }
        //*************************************************************************
        #endregion

        public void setShowTabControl(string tabName)
        {
            switch (tabName)
            {
                case "methodsTabControl":
                    this.TabControl.SelectedTab = methodsTabControl;
                    break;
                case "attributesTabControl":
                    this.TabControl.SelectedTab = attibutesTabControl;
                    break;
                case "NFRTabControl":
                    this.TabControl.SelectedTab = NFRTabControl;
                    break;
                default:
                    this.TabControl.SelectedTab = genenralTabControl;
                    break;
            }
        }

        private void selectedRow(RichTextBox textBox)
        {
            if (textBox.Text.Length != 0)
            {
                int myStart = textBox.SelectionStart;//鼠标点击位置
                myLine = textBox.GetLineFromCharIndex(myStart);//获取选中行号(从0开始)
                if (textBox.Lines[myLine].Length > 0)
                {
                    //计算选中的行的开始位置
                    offSet = 0;
                    for (int i = 0; i < myLine; i++)
                    {
                        offSet += textBox.Lines[i].Length;
                        offSet += 1;//"\n"
                    }
                    //选中行
                    textBox.Select(offSet, textBox.Lines[myLine].Length);
                    hasSelectedItem = true;
                }
                else
                    hasSelectedItem = false;
            }
            else
                hasSelectedItem = false;

        }
        [DllImport("user32.dll ")]//要搞清楚其原理
        public static extern System.Int32 HideCaret(System.IntPtr hwnd);

        //对象关系
        private void relationType_SelectedValueChanged(object sender, EventArgs e)
        {
            switch(relationType.SelectedItem.ToString())
            {
                case "All Relations":
                    relationsShowBox.Text = "All Relations";
                    break;
                case "Realization":
                    relationsShowBox.Text = "Realization";
                    break;
                case "Association":
                    relationsShowBox.Text = "Association";
                    break;
                case "Generalization":
                    relationsShowBox.Text = "Generalization";
                    break;
                case "Dependency":
                    relationsShowBox.Text = "Dependency";
                    break;
                default :
                    MessageBox.Show("Internal Error!");
                    break;
            }

        }
        
    }
}
